#ifndef SIMPLE_SUPPORT_ALGORITHM_FIND_HPP
#define SIMPLE_SUPPORT_ALGORITHM_FIND_HPP

#include <type_traits> // std::enable_if_t

#include "../function_utils.hpp" // invoke
#include "traits.hpp" // is_iterable_v
#include "reaches.hpp" // reaches


namespace simple::support
{

	template <typename It, typename End, typename Value,
		std::enable_if_t<is_iterable_v<It>>* = nullptr>
		// TODO: reachable<End, It>
	[[nodiscard]] constexpr
	It find(It begin, const End& end, const Value& value)
	// TODO; noexcept(...)
	{
		while(not reaches(begin, end) && *begin != value)
			++begin;
		return begin;
	}

	template <typename It, typename End, typename Predicate,
		std::enable_if_t<is_iterable_v<It>>* = nullptr>
		// TODO: reachable<End, It>
	[[nodiscard]] constexpr
	It find_if(It begin, const End& end, Predicate&& predicate)
	// TODO; noexcept(...)
	{
		while(not reaches(begin, end) &&
			not support::invoke(std::forward<Predicate>(predicate), *begin))
			++begin;
		return begin;
	}

} // namespace simple::support

#endif /* end of include guard */
